
package cz.results.perzist.db4o;


import com.db4o.*;
import com.db4o.events.*;
import com.db4o.messaging.*;

import cz.results.perzist.DbClient;
import java.util.Iterator;
import java.io.IOException;

public class DbClientDb4o implements DbClient {
    
    private final static String HOST="192.168.0.100";
    private final static int    PORT=4488;
    private final static String USER="test";
    private final static String PSWD="test";
    
    private ObjectContainer dbClient = null;
    
    private String host;
    private int    port;
    private String user;
    private String pswd;
    
    public DbClientDb4o(String host, int port, String user, String pswd) throws IOException {
        dbSetConfig();
        this.host = host;
        this.port = port;
        this.user = user;
        this.pswd = pswd;
        dbClient  = dbOpenClient();
        registerCallback();
    }
    
    
    public DbClientDb4o() throws IOException {
        this(HOST, PORT, USER, PSWD);
    }
    
    private ObjectContainer dbOpenClient() throws IOException {
        return Db4o.openClient(host, port, user, pswd);
    }
    
    public void registerCallback(){
        EventRegistry registry =  EventRegistryFactory.forObjectContainer(dbClient);
        
        registry.creating().addListener(new EventListener4() {
            public void onEvent(Event4 e, EventArgs args) {
                ObjectEventArgs queryArgs = ((ObjectEventArgs) args);
                Object obj = queryArgs.object();
                System.out.println("CALLBACK pro creating()");
            }
        });

        registry.updated().addListener(new EventListener4() {
            public void onEvent(Event4 e, EventArgs args) {
                ObjectEventArgs queryArgs = ((ObjectEventArgs) args);
                Object obj = queryArgs.object();
                System.out.println("CALLBACK pro updated()");
            }
        });
        
    }
    // end registerCallback
    
    public ObjectContainer dbGetClient() throws IOException {
        if (dbClient == null) {
            dbClient = dbOpenClient();
        }
        return dbClient;
    }
    
    public void dbCloseClient() {
        if (dbClient != null) {
            dbClient.commit();
            dbClient.close();
            dbClient = null;
        }
        
    }
    
    public void dbWrite(Object ob) throws IOException {
        dbGetClient().set(ob);
        dbGetClient().commit();
    }
    
    public ObjectSet dbRead(Object ob) throws IOException {
        ObjectSet os = dbGetClient().get(ob);
        for (Iterator i = os.iterator(); i.hasNext();) {
            refresh(i.next());
        }
        return os;
    }
    
    public void dbDelete(Object ob) throws IOException {
        dbGetClient().delete(ob);
        dbGetClient().commit();
    }
    
    
    public void dbZap(Object ob) throws IOException {
        ObjectSet os = dbRead(ob);
        for (Iterator i = os.iterator(); i.hasNext();) {
            dbDelete(i.next());
        }
    }
    
    public void dbInit() throws IOException {
        dbZap(new Object());
    }
    
    public int dbRecCount(Object ob) throws IOException {
        return dbRead(ob).size();
    }
    
    public void dbSetConfig() {
        // Default konfigurace - spolecna pro server i klinety
        DbConfigDb4o.setDefaultConfig();
        
        // Individualni konfigurace klienta
        Db4o.configure().messageLevel(0);
/*
        Db4o.configure().objectClass("cz.results.winter6.model.StartSubjekt").cascadeOnUpdate(true);
        Db4o.configure().objectClass("cz.results.winter6.model.StartSubjekt").cascadeOnActivate(true);
        Db4o.configure().objectClass("cz.results.winter6.model.StartSubjekt").cascadeOnDelete(true);
 
        Db4o.configure().objectClass("cz.results.winter6.model.Ciselnik").cascadeOnUpdate(true);
        Db4o.configure().objectClass("cz.results.winter6.model.Ciselnik").cascadeOnActivate(true);
        Db4o.configure().objectClass("cz.results.winter6.model.Ciselnik").cascadeOnDelete(true);
 */
    }
    
    public void dbDefragment(String message) throws IOException {
        MessageSender messageSender = dbGetClient().ext().configure().clientServer().getMessageSender();
        messageSender.send(new DefragmentServer(message));
    }
    
    public void dbShutServer(String message) throws IOException {
        MessageSender messageSender = dbGetClient().ext().configure().clientServer().getMessageSender();
        messageSender.send(new StopServer(message));
    }
    
    public Object refresh(Object obj) {
        dbClient.deactivate(obj, Integer.MAX_VALUE);
        dbClient.activate(obj, Integer.MAX_VALUE);
        return obj;
    }
    
    
    
}